home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Panel Editor / Source / Scrollbar.cpp < prev    next >
Encoding:
Text File  |  1995-12-08  |  9.3 KB  |  349 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Scrollbar.cpp
  3.  
  4.     Contains:    Scrollbar class implementation
  5.  
  6.     Written by:    Steve Smith
  7.     
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- Compiler/Preprocessor Switches --
  12.  
  13. #ifndef _COMPILERDEFS_
  14. #include "CompDefs.h"
  15. #endif
  16.  
  17. // -- OpenDoc Utilities --
  18.  
  19. #ifndef _EXCEPT_
  20. // Exceptions define several important macros (ie. CHECKENV)
  21. // which are used in the SOM method dispatch glue. If Except.h
  22. // is not included early enough, exceptions may not be thrown
  23. // correctly when returning from a SOM method with the "ev" parameter set.
  24. #include <Except.h>
  25. #endif
  26.  
  27. // -- PanelEditor Includes --
  28.  
  29. #ifndef _SCROLLBAR_
  30. #include "Scrollbar.h"
  31. #endif
  32.  
  33. #ifndef _PANELEDITOR_
  34. #include "PanelEditor.h"
  35. #endif
  36.  
  37. #ifndef _PANELEDITORUTILS_
  38. #include "PanelEditorUtils.h"
  39. #endif
  40.  
  41. #ifndef _PANELEDITORDEF_
  42. #include "PanelEditorDef.h"
  43. #endif
  44.  
  45. // -- OpenDoc Includes --
  46.  
  47. #ifndef _ODTYPES_
  48. #include <ODTypes.h>
  49. #endif
  50.  
  51. #ifndef SOM_ODFacet_xh
  52. #include <Facet.xh>
  53. #endif
  54.  
  55. #ifndef SOM_ODFrame_xh
  56. #include <Frame.xh>
  57. #endif
  58.  
  59. #ifndef SOM_ODShape_xh
  60. #include <Shape.xh>
  61. #endif
  62.  
  63. #ifndef SOM_ODTransform_xh
  64. #include <Trnsform.xh>
  65. #endif
  66.  
  67. // -- OpenDoc Utilities --
  68.  
  69. #ifndef _FOCUSLIB_
  70. #include <FocusLib.h>
  71. #endif
  72.  
  73. #ifndef _ODUTILS_
  74. #include <ODUtils.h>
  75. #endif
  76.  
  77. #ifndef _TEMPOBJ_
  78. #include <TempObj.h>
  79. #endif
  80.  
  81. #ifndef _ODDEBUG_
  82. #include <ODDebug.h>
  83. #endif
  84.  
  85. #pragma segment PanelEditorScrollbar
  86.  
  87.  
  88. //------------------------------------------------------------------------------
  89. // Method:        Constructor
  90. //------------------------------------------------------------------------------
  91.  
  92. CScrollbar::CScrollbar()
  93. {
  94.     fFacet = kODNULL;
  95.     fWindow = kODNULL;
  96.     fControl = kODNULL;
  97.     fInited = kODFalse;
  98. }
  99.  
  100. //------------------------------------------------------------------------------
  101. // Method:        Destructor
  102. //------------------------------------------------------------------------------
  103.  
  104. CScrollbar::~CScrollbar()
  105. {
  106.     ASSERT(fInited != kODFalse, kAssertionFailed);
  107.     ASSERT(fFacet != kODNULL, kAssertionFailed);
  108.     
  109.     Environment* ev = somGetGlobalEnvironment();
  110.     CFocusFrame initiateDrawing(ev, fFacet);
  111.  
  112. // Possibly dangerous, if GrafPort is destroyed before frame is cleaned up, the
  113. // control will no longer exist... any way to check for dead control?
  114. //    DisposeControl(fControl);
  115. }
  116.  
  117. //------------------------------------------------------------------------------
  118. // Method:        InitScrollbar
  119. //------------------------------------------------------------------------------
  120.  
  121. void CScrollbar::InitScrollbar(Environment* ev, ODFacet* facet, Rect ctrlRect)
  122. {
  123.     ASSERT(facet != kODNULL, kAssertionFailed);
  124.  
  125.     ODWindow* odWindow = facet->GetWindow(ev);
  126.     
  127.     fFacet = facet;
  128.     fWindow = (WindowPtr) odWindow->GetPlatformWindow(ev);
  129.  
  130.     CFocusFrame initiateDrawing(ev, fFacet);
  131.     fControl = NewControl(fWindow,&ctrlRect,"\p",false,0,0,0,scrollBarProc,0x0L);
  132.     
  133.     fInited = kODTrue;
  134. }
  135.  
  136. //------------------------------------------------------------------------------
  137. // Method:        Size
  138. // Description:    Resize the control using the parameters passed in.
  139. //------------------------------------------------------------------------------
  140.  
  141. void CScrollbar::Size(ODUShort width, ODUShort height)
  142. {
  143.     ASSERT(fInited != kODFalse, kAssertionFailed);
  144.     ASSERT(fControl != kODNULL, kAssertionFailed);
  145.     
  146.     Environment* ev = somGetGlobalEnvironment();
  147.     CFocusFrame initiateDrawing(ev, fFacet);
  148.  
  149.     SizeControl(fControl,width,height); 
  150. }
  151.  
  152. //------------------------------------------------------------------------------
  153. // Method:        Size
  154. // Description:    Size the control based on the bounding box of the list frame.
  155. //------------------------------------------------------------------------------
  156.  
  157. void CScrollbar::Size()
  158. {
  159.     ASSERT(fInited != kODFalse, kAssertionFailed);
  160.     ASSERT(fFacet != kODNULL, kAssertionFailed);
  161.  
  162.     Environment* ev = somGetGlobalEnvironment();
  163.  
  164.     Rect bounds;
  165.     GetQDFrameBounds(ev, fFacet->GetFrame(ev), &bounds);
  166.     
  167.     this->Size(16,(bounds.bottom-bounds.top)); 
  168. }
  169.  
  170. //------------------------------------------------------------------------------
  171. // Method:        Dirty
  172. // Description: Mark the scroll bar size as "dirty". Next time we draw it should
  173. //                be updated.
  174. //------------------------------------------------------------------------------
  175.  
  176. void CScrollbar::Dirty(ODUShort numItems)
  177. {
  178.     ASSERT(fInited != kODFalse, kAssertionFailed);
  179.  
  180.     fDirty = kODTrue;
  181.     fNumItems = numItems;
  182. }
  183.  
  184. //------------------------------------------------------------------------------
  185. // Method:        Draw
  186. // Description:    Resize the control if it's dirty (which causes drawing as a side
  187. //                effect) or draw the control if it's not.
  188. //------------------------------------------------------------------------------
  189.  
  190. void CScrollbar::Draw()
  191. {
  192.     ASSERT(fInited != kODFalse, kAssertionFailed);
  193.     ASSERT(fControl != kODNULL, kAssertionFailed);
  194.  
  195.     // We always create the control invisible.
  196.     // Make it visible when we draw.
  197.     if ( (**fControl).contrlVis != 0xFF )
  198.         ShowControl(fControl);
  199.  
  200.     // The scroll bar will be "dirty" if it needs to be resized or
  201.     // have its limits adjusted. We use the dirty mechanism to delay
  202.     // the immediate drawing of the control when such calls are made.
  203.     if ( fDirty )
  204.     {
  205.         this->Size();
  206.         this->Adjust(fNumItems);
  207.         fDirty = kODFalse;
  208.     }
  209.     else Draw1Control(fControl);
  210. }
  211.  
  212. //------------------------------------------------------------------------------
  213. // Method:        Adjust
  214. // Description:    Calculate the limits for the scrollbar based on the number of
  215. //                items passed in.
  216. //------------------------------------------------------------------------------
  217.  
  218. void CScrollbar::Adjust(ODUShort numItems)
  219. {
  220.     ASSERT(fInited != kODFalse, kAssertionFailed);
  221.     ASSERT(fControl != kODNULL, kAssertionFailed);
  222.  
  223.     Rect ctrlRect = (**fControl).contrlRect;
  224.     
  225.     ODSShort space = (ctrlRect.bottom-ctrlRect.top+1)/kListItemHeight;
  226.     
  227.     ODUShort value;
  228.     if ( numItems-space > 0)  value = (numItems - space);
  229.     else value = 0;
  230.     
  231.     this->SetLimits(value);
  232. }
  233.  
  234. //------------------------------------------------------------------------------
  235. // Method:        SetLimits
  236. // Description:    Set the control min/max limits. This causes drawing to occur.
  237. //------------------------------------------------------------------------------
  238.  
  239. void CScrollbar::SetLimits(ODUShort max, ODUShort min)
  240. {
  241.     ASSERT(fInited != kODFalse, kAssertionFailed);
  242.     ASSERT(fControl != kODNULL, kAssertionFailed);
  243.     ASSERT(fFacet != kODNULL, kAssertionFailed);
  244.  
  245.     Environment* ev = somGetGlobalEnvironment();
  246.     CFocusFrame initiateDrawing(ev, fFacet);
  247.  
  248.     SetControlMinimum(fControl, min);
  249.     SetControlMaximum(fControl, max);
  250. }
  251.  
  252. //------------------------------------------------------------------------------
  253. // Method:        HitTest
  254. // Description:    Determine whether the control was clicked on, and if so where.
  255. //                Store the last valid contact point (partcode) for later use.
  256. //------------------------------------------------------------------------------
  257.  
  258. ODBoolean CScrollbar::HitTest(Point where)
  259. {
  260.     ASSERT(fInited != kODFalse, kAssertionFailed);
  261.     ASSERT(fControl != kODNULL, kAssertionFailed);
  262.     ASSERT(fFacet != kODNULL, kAssertionFailed);
  263.     ASSERT(fWindow != kODNULL, kAssertionFailed);
  264.  
  265.     Environment* ev = somGetGlobalEnvironment();
  266.     CFocusFrame initiateDrawing(ev, fFacet);
  267.  
  268.     ControlHandle control = kODNULL;
  269.     fPartCode = FindControl(where, fWindow, &control);
  270.     
  271.     if ( control != fControl )
  272.         fPartCode = 0;
  273.     
  274.     return fPartCode;
  275. }
  276.  
  277. //------------------------------------------------------------------------------
  278. // Method:        Scroll
  279. // Description:    Handle scrolling. Install a scroll tracking proc if the user is
  280. //                not clicking on the "thumb". Scrolling of the content is
  281. //                achieved by translating the internal transform of the list
  282. //                frame.
  283. //------------------------------------------------------------------------------
  284.  
  285. void CScrollbar::Scroll(Environment* ev, ODFrame* frame, Point where)
  286. {
  287.     ASSERT(fInited != kODFalse, kAssertionFailed);
  288.     ASSERT(fFacet != kODNULL, kAssertionFailed);
  289.     ASSERT(fControl != kODNULL, kAssertionFailed);
  290.  
  291.     if ( fPartCode != 0 )
  292.     {
  293.         CFocusFrame initiateDrawing(ev, fFacet);
  294.     
  295.         ScrollDataRec* scrollData = (ScrollDataRec*) ODNewPtr(sizeof(ScrollDataRec));
  296.         
  297.         scrollData->frame = frame;
  298.         scrollData->ev = ev;
  299.         
  300.         if ( fPartCode == kControlIndicatorPart )
  301.         {
  302.             // Determine which direction the user scrolled (up/down)
  303.             
  304.             short vScroll = GetControlValue(fControl);
  305.             
  306.             TrackControl(fControl, where, kODNULL);
  307.                         
  308.             vScroll = GetControlValue(fControl) - vScroll;
  309.             
  310.             if ( vScroll != 0 )
  311.             {
  312.                 // Adjust the internal transform of the list frame to affect
  313.                 // scrolling of the list.
  314.                 
  315.                 TempODTransform intTransform = 
  316.                         scrollData->frame->AcquireInternalTransform(ev, kODNULL);
  317.         
  318.                 Point offset = intTransform->GetQDOffset(ev);
  319.                 offset.v += (-vScroll*kListItemHeight);
  320.                 intTransform->SetQDOffset(ev, &offset);
  321.                 
  322.                 scrollData->frame->ChangeInternalTransform(ev, intTransform, kODNULL);
  323.                 scrollData->frame->Invalidate(ev, kODNULL, kODNULL);
  324.             }
  325.         }
  326.         else
  327.         {
  328.             ControlActionUPP scrollProcUPP = NewControlActionProc(ScrollProc);
  329.                         
  330.             // Stuff the scroll data structure into the scroll bar we are 
  331.             // working with.
  332.             SetControlReference(fControl, (long)scrollData);
  333.             
  334.             // Using the scrollProc, track the users actions.
  335.             TrackControl(fControl, where, scrollProcUPP);
  336.             
  337.             // Clear the refcon to avoid confusion.
  338.             SetControlReference(fControl, 0x0L);
  339.             
  340.             // Delete the routine descriptor.
  341.             DisposeRoutineDescriptor(scrollProcUPP);
  342.         }
  343.         
  344.         ODDisposePtr((ODPtr)scrollData);
  345.     }
  346. }
  347.  
  348.  
  349.